home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / UI101.ZIP / IO / GR / GR_IBMPC.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  34KB  |  1,456 lines

  1. /****************************************************************
  2.  
  3.     gr_ibmpc.c      Implementation of Bywater Graphics Interface
  4.             for IBM PC (tm) and compatibles
  5.             utilizing Microsoft QuickC (tm)
  6.  
  7.             Copyright (c) 1991, Ted A. Campbell
  8.  
  9.             Bywater Software
  10.             P. O. Box 4023 
  11.             Duke Station 
  12.             Durham, NC  27706
  13.  
  14.             email: tcamp@hercules.acpub.duke.edu
  15.  
  16.     Copyright and Permissions Information:
  17.  
  18.     All U.S. and international copyrights are claimed by the
  19.     author. The author grants permission to use this code
  20.     and software based on it under the following conditions:
  21.     (a) in general, the code and software based upon it may be 
  22.     used by individuals and by non-profit organizations; (b) it
  23.     may also be utilized by governmental agencies in any country,
  24.     with the exception of military agencies; (c) the code and/or
  25.     software based upon it may not be sold for a profit without
  26.     an explicit and specific permission from the author, except
  27.     that a minimal fee may be charged for media on which it is
  28.     copied, and for copying and handling; (d) the code must be 
  29.     distributed in the form in which it has been released by the
  30.     author; and (e) the code and software based upon it may not 
  31.     be used for illegal activities. 
  32.  
  33. ****************************************************************/
  34.  
  35. #include "stdio.h"
  36. #include "dos.h"
  37. #include "graph.h"
  38. #include "bw.h"
  39. #include "gr.h"
  40. #include "malloc.h"
  41.  
  42. /*#define DEBUG */          /* Include Debugging info */
  43. #define SET_MONOVGA     FALSE
  44. #define CHECK_PARAMS    TRUE
  45. #define LINE_BLIT       TRUE
  46. #define SIGNON          FALSE
  47. #define DEF_LINE        FALSE
  48. #define DEF_RECTANGLE   FALSE
  49. #define DEF_CIRCLE      FALSE
  50. #define HMP_RATIO       8             /* Horizontal Mickey/Pixel Ratio */
  51. #define VMP_RATIO       16            /* Vertical Mickey/Pixel Ratio */
  52. #define ACC             30
  53. #define IMAGES          64
  54.  
  55. int     gr_screens;
  56. int    gr_colors;
  57. int    gr_pxsize;
  58. int    gr_pysize;
  59. int    gr_ismouse;
  60. int     gr_clipping = TRUE;
  61. int     gr_blitting;
  62. int     gr_saving = TRUE;
  63.  
  64. struct gr_window *ibm_window;   /* structure for window info    */
  65. int ibm_px;             /* relative size of pixel, x axis       */
  66. int ibm_py;             /* relative size of pixel, y axis       */
  67. int ibm_vmode;          /* video mode for IBM equipment         */
  68. int ibm_imode;          /* initial video mode */
  69. int ibm_ishidden = FALSE; /* boolean: is display "hidden"       */
  70. struct videoconfig
  71.     ibm_vc;         /* internal structure for video configuration */
  72. int msm_exist = FALSE;  /* boolean:  is there a mouse?          */
  73. long    miaddr;                 /* mouse interupt routine address */
  74. union   REGS ibm_registers;     /* cpu register for use of DOS calls */
  75. struct  SREGS segreg;           /* cpu segment registers             */
  76. static  int msm_buttons;        /* number of buttons on the mouse */
  77. char    far *hgc_location;      /* location to change for Hercules */
  78. static  int msm_oldbut;         /* previous state of mouse buttons */
  79. static  int msm_showcounter;    /* keep track of mouse show status */
  80. static  int m_col, m_row;       /* current column, row */
  81. static  int m_but;              /* right button depressed */
  82. char    fontfile[12] = "*.fon";
  83. char    *ibm_images[ IMAGES ];  /* array of pointers to image buffers */
  84.  
  85. #if     LINE_BLIT
  86. char far *xfr_mem;
  87. #else
  88. char huge *xfr_mem;
  89. #endif
  90.  
  91. unsigned char fs[ 20 ];
  92.  
  93. unsigned char fr[ 40 ];
  94.  
  95. struct  _fontinfo fi;
  96.  
  97. /***    Define fill grids ***/
  98.  
  99. char _fill_blank[ 8 ] = {   0,   0,   0,   0,   0,   0,   0,   0 };
  100. char _fill_grid[ 8 ]  = { 170,  85, 170,  85, 170,  85, 170,  85 };
  101. char _fill_full[ 8 ]  = { 255, 255, 255, 255, 255, 255, 255, 255 };
  102. char _fill_hatch[ 8 ] = {  17, 255,  68,  68,  68, 255,  17,  17 };
  103.  
  104. /****************************************************************
  105.  
  106.     gr_init()
  107.  
  108. ****************************************************************/
  109.  
  110. gr_init( window, font_path )
  111.    struct gr_window *window;
  112.    char *font_path;
  113.    {
  114.    int font_ret;
  115.    static char ff[ 64 ];
  116.    register int i;
  117.  
  118.    ibm_window = window;
  119.  
  120.    /* Set font */
  121.  
  122.    if ( font_path != NULL )
  123.       {
  124.       sprintf( ff, "%s%s", font_path, fontfile );
  125.       }
  126.    else
  127.       {
  128.       strcpy( ff, fontfile );
  129.       }
  130.  
  131.    if ( ( font_ret = _registerfonts( ff ) ) <= 0 )
  132.       {
  133.       strcpy ( ff, "../../fonts" );
  134.       if ( ( font_ret = _registerfonts( ff ) ) <= 0 )
  135.      {
  136.      fprintf( stderr, "Can't find font files (path: %s).\n", ff );
  137.      exit( 0 );
  138.      }
  139.       }
  140.  
  141.    /* Get the video configuration to learn about hardware */
  142.  
  143.    _getvideoconfig( &ibm_vc );
  144.    ibm_imode = ibm_vc.mode;
  145.  
  146.    switch( ibm_vc.adapter )
  147.       {
  148.       case _HGC:
  149.          ibm_vmode = _HERCMONO;
  150.          ibm_px = 30;
  151.          ibm_py = 45;
  152.          break;
  153.       case _CGA:
  154.       case _OCGA:
  155.          ibm_vmode = _HRESBW;
  156.          ibm_px = 29;
  157.          ibm_py = 69;
  158.          break;
  159.       case _VGA:
  160.       case _OVGA:
  161.       case _MCGA:
  162.       case _EGA:
  163.       case _OEGA:
  164.          ibm_vmode = _ERESCOLOR;
  165. #ifdef OLD_DEBUG
  166.      fprintf( stderr, "VGA: monitor is %d \n", ibm_vc.adapter );
  167.      getchar();
  168. #endif
  169.      ibm_px = 40;
  170.          ibm_py = 50;
  171.          break;
  172.       default:
  173.          printf( "An appropriate video mode could not be located\n" );
  174.          exit( 0 );
  175.          break;
  176.       }
  177.  
  178.    /* If there is a mouse, initialize it now */
  179.  
  180.    msm_init();
  181.  
  182.    /* set the video mode */
  183.  
  184.    if ( ibm_imode != ibm_vmode )
  185.       {
  186.      _setvideomode( ibm_vmode );
  187. #ifdef OLD_DEBUG
  188.       fprintf( stderr, "INIT....." );
  189.       getchar();
  190. #endif
  191.       }
  192.    else
  193.       {
  194. #ifdef OLD_DEBUG
  195.       fprintf( stderr, "No need to initialize....." );
  196.       getchar();
  197. #endif
  198.       }
  199.  
  200.    /* Get the video configuration again */
  201.  
  202.    _getvideoconfig( &ibm_vc );
  203.  
  204.    /* allocate transfer memory area */
  205.  
  206. #if     LINE_BLIT
  207.    if ( ( xfr_mem = malloc( (size_t) _imagesize( 0, 0,
  208.       ibm_vc.numxpixels, 1 ) )) == NULL )
  209. #else
  210.    if ( ( xfr_mem
  211.       = halloc( (long) 1, (size_t) _imagesize( 0, ibm_vc.numypixels,
  212.       ibm_vc.numxpixels, 0 ) )) == NULL )
  213. #endif
  214.       {
  215.       gr_deinit();
  216.       fprintf( stderr,
  217.      "gr: failed to allocate memory for transfer buffer\n" );
  218.       exit( 0 );
  219.       }
  220.  
  221.    /* Reset mouse cursor lines + columns */
  222.  
  223.    if ( msm_exist == TRUE )
  224.       {
  225. #ifdef WHYDOTHIS
  226.       msm_position( 0, 0 );
  227. #endif
  228.       msm_showcounter = -1;
  229.       msm_show();
  230.       gr_ismouse = TRUE;
  231. #ifdef  OLD_DEBUG
  232.       fprintf( stderr, "yes, virginia, there is a mouse...\n" );
  233.       kb_rx();
  234. #endif
  235.       }
  236.    else
  237.       {
  238.       gr_ismouse = FALSE;
  239.       }
  240.  
  241. #ifdef REALLYLETSDONTDOTHIS
  242.     _setactivepage ( 0 );
  243.     _clearscreen( _GCLEARSCREEN );
  244.     _setactivepage ( 1 );
  245.     _clearscreen( _GCLEARSCREEN );
  246. #endif
  247.     _setactivepage ( 0 );
  248.     _setvisualpage ( 0 );
  249.  
  250.    /* Transfer video configuration information to the gr_window struct */
  251.  
  252.    window->initialized = TRUE;
  253.    window->xmax = ibm_vc.numxpixels - 1;
  254.    window->ymax = ibm_vc.numypixels - 1;
  255.    gr_screens = ibm_vc.numvideopages;
  256.    if ( gr_screens > 1 )
  257.       {
  258.       gr_blitting = TRUE;
  259.       }
  260.    else
  261.       {
  262.       gr_blitting = FALSE;
  263.       }
  264.  
  265. #if SET_MONOVGA
  266.    if ( ( ibm_vmode == _ERESCOLOR ) && ( ibm_vc.adapter == _ANALOGMONO ))
  267.       {
  268.       gr_colors = 2;                 /* for mono VGA */
  269.       }
  270.    else
  271.       {
  272.       gr_colors = ibm_vc.numcolors;
  273.       }
  274. #else
  275.    gr_colors = ibm_vc.numcolors;
  276. #endif
  277.  
  278.    gr_pxsize = ibm_px;
  279.    gr_pysize = ibm_py;
  280.  
  281.    /* gr signon message */
  282.  
  283. #if SIGNON
  284.  
  285.    printf( "Bywater Graphics Interface Standard Implementation\n" );
  286.    printf( "Copyright (c) 1990, Ted A. Campbell\n" );
  287.    switch( ibm_vmode )
  288.       {
  289.       case _HERCMONO:
  290.          printf( "Hercules (tm) " );
  291.          break;
  292.       case _HRESBW:
  293.          printf( "CGA " );
  294.          break;
  295.       case _ERESCOLOR:
  296.          printf( "EGA or VGA " );
  297.          break;
  298.       }
  299.    printf( "or compatible graphics detected\n" );
  300.    printf( "%dx%d pixels resolution in %d colors\n",
  301.       ibm_vc.numxpixels, ibm_vc.numypixels, ibm_vc.numcolors );
  302.    printf( "%d kbytes of video RAM in %d video page(s)\n",
  303.       ibm_vc.memory, ibm_vc.numvideopages );
  304.    if ( msm_exist != FALSE )
  305.       {
  306.       printf( "Mouse device detected. \n" );
  307.       }
  308.    printf( "Please wait while font is loaded...\n" );
  309.  
  310. #endif
  311.  
  312.    /* set image buffer pointers to NULL */
  313.  
  314.    for ( i = 0; i < IMAGES; ++i )
  315.       {
  316.       ibm_images[ i ] = NULL;
  317.       }
  318.  
  319.    ibm_screen( GR_PRIMARY );
  320.    gr_font( GR_PRIMARY, F_DEFAULT, ibm_vc.numypixels / 25 );
  321.  
  322.    }
  323.  
  324. /****************************************************************
  325.  
  326.     gr_deinit()
  327.  
  328. ****************************************************************/
  329.  
  330. gr_deinit()
  331.    {
  332. #if     LINE_BLIT
  333.    _ffree( xfr_mem );
  334. #else
  335.    hfree( xfr_mem );
  336. #endif
  337.  
  338.    /* hide the mouse in case we are returning to a graphics-based
  339.       program that uses the mouse */
  340.  
  341.    msm_hide();
  342.  
  343.    /* reset video mode if necessary */
  344.  
  345.    if ( ibm_vmode != ibm_imode )
  346.       {
  347.       _setvideomode( _DEFAULTMODE );
  348. #ifdef OLD_DEBUG
  349.       fprintf( stderr, "Deinitialized....." );
  350.       getchar();
  351. #endif
  352.       }
  353.    else
  354.       {
  355. #ifdef OLD_DEBUG
  356.       fprintf( stderr, "No need to deinitialize....." );
  357.       getchar();
  358. #endif
  359.       }
  360.    }
  361.  
  362. /****************************************************************
  363.  
  364.     gr_cls()
  365.  
  366. ****************************************************************/
  367.  
  368. gr_cls( screen )
  369.    int screen;
  370.    {
  371.    ibm_screen( screen );
  372.    if ( screen != GR_HIDDEN )
  373.       {
  374.       msm_hide();
  375.       }
  376.    _clearscreen( _GCLEARSCREEN );
  377.    if ( screen != GR_HIDDEN )
  378.       {
  379.       msm_show();
  380.       }
  381.    }
  382.  
  383. /****************************************************************
  384.  
  385.     gr_pixel()
  386.  
  387. ****************************************************************/
  388.  
  389. gr_pixel( screen, x, y, color )
  390.    int screen;
  391.    int x, y;
  392.    int color;
  393.    {
  394.  
  395. #if CHECK_PARAMS
  396.    if ( ( x < 0 ) || ( x > ibm_window->xmax ))
  397.       {
  398.       sprintf( bw_ebuf, "[pr:] gr_pixel(): x value is %d", x );
  399.       bw_error( bw_ebuf );
  400.       return BW_ERROR;
  401.       }
  402.    if ( ( y < 0 ) || ( y > ibm_window->ymax ))
  403.       {
  404.       sprintf( bw_ebuf, "[pr:] gr_pixel(): y value is %d", y );
  405.       bw_error( bw_ebuf );
  406.       return BW_ERROR;
  407.       }
  408. #endif
  409.  
  410.    ibm_screen( screen );
  411.    if ( screen != GR_HIDDEN )
  412.       {
  413.       msm_hide();
  414.       }
  415.    _setcolor( ibm_color( color ) );
  416.    _setpixel( x, ibm_window->ymax - y );
  417.    if ( screen != GR_HIDDEN )
  418.       {
  419.       msm_show();
  420.       }
  421.    }
  422.          
  423. /****************************************************************
  424.  
  425.     gr_line()
  426.  
  427. ****************************************************************/
  428.  
  429. gr_line( screen, x1, y1, x2, y2, color, style )
  430.    int screen;
  431.    int x1, y1, x2, y2;
  432.    int color, style;
  433.    {
  434.  
  435. #if CHECK_PARAMS
  436.    if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
  437.       {
  438.       sprintf( bw_ebuf, "[pr:] gr_line(): x1 value is %d", x1 );
  439.       bw_error( bw_ebuf );
  440.       return BW_ERROR;
  441.       }
  442.    if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
  443.       {
  444.       sprintf( bw_ebuf, "[pr:] gr_line(): x2 value is %d", x2 );
  445.       bw_error( bw_ebuf );
  446.       return BW_ERROR;
  447.       }
  448.    if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
  449.       {
  450.       sprintf( bw_ebuf, "[pr:] gr_line(): y1 value is %d", y1 );
  451.       bw_error( bw_ebuf );
  452.       return BW_ERROR;
  453.       }
  454.    if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
  455.       {
  456.       sprintf( bw_ebuf, "[pr:] gr_line(): y2 value is %d", y2 );
  457.       bw_error( bw_ebuf );
  458.       return BW_ERROR;
  459.       }
  460. #endif
  461.  
  462. #if     DEF_LINE
  463.    def_line( screen, x1, y1, x2, y2, color, style );
  464. #else
  465.    ibm_screen( screen );
  466.    _setcolor( ibm_color( color ));
  467.    switch( style )
  468.       {
  469.       case HOLLOW:
  470.          _setlinestyle( 0 );
  471.          break;
  472.       case GRID:
  473.       case HATCH:
  474.          _setlinestyle( 85 + (256*85) );
  475.          break;
  476.       default:                        /* SOLID is default     */
  477.          _setlinestyle( 0xffff );
  478.          break;
  479.       }
  480.    _moveto( x1, ibm_window->ymax - y1 );
  481.    if ( screen != GR_HIDDEN )
  482.       {
  483.       msm_hide();
  484.       }
  485.    _lineto( x2, ibm_window->ymax - y2 );
  486.    if ( screen != GR_HIDDEN )
  487.       {
  488.       msm_show();
  489.       }
  490. #endif
  491.    }
  492.  
  493. /****************************************************************
  494.  
  495.     gr_text()
  496.  
  497. ****************************************************************/
  498.  
  499. gr_text( screen, x, y, string, foreground, background )
  500.    int screen;
  501.    int x, y;
  502.    int foreground, background;
  503.    char *string;
  504.    {
  505.  
  506. #if CHECK_PARAMS
  507.    if ( ( x < 0 ) || ( x > ibm_window->xmax ))
  508.       {
  509.       sprintf( bw_ebuf, "[pr:] gr_text(): x value is %d", x );
  510.       bw_error( bw_ebuf );
  511.       return BW_ERROR;
  512.       }
  513.    if ( ( y < 0 ) || ( y > ibm_window->ymax ))
  514.       {
  515.       sprintf( bw_ebuf, "[pr:] gr_text(): y value is %d", y );
  516.       bw_error( bw_ebuf );
  517.       return BW_ERROR;
  518.       }
  519. #endif
  520.  
  521.    ibm_screen( screen );
  522.  
  523.    _setcolor( ibm_color( background ) );
  524.    _setbkcolor( (long) ibm_color( background ) );
  525.    _setfillmask( _fill_full );
  526.    _setlinestyle( 0xffff );
  527.  
  528.    if ( screen != GR_HIDDEN )
  529.       {
  530.       msm_hide();
  531.       }
  532.  
  533.    _rectangle( _GFILLINTERIOR, x,
  534.       ibm_window->ymax - ( y + ibm_window->fysize ),
  535.       x + ((int) _getgtextextent( ((unsigned char far *) string ) )) + 1,
  536.       ibm_window->ymax - ( y ) );
  537.    _moveto( x, ibm_window->ymax - ( y + ibm_window->fysize ) );
  538.    _setcolor( ibm_color( foreground ) );
  539.    _outgtext( string );
  540.  
  541.    if ( screen != GR_HIDDEN )
  542.       {
  543.       msm_show();
  544.       }
  545.    }
  546.  
  547. /****************************************************************
  548.  
  549.     gr_strlen()
  550.  
  551. ****************************************************************/
  552.  
  553. unsigned int
  554. gr_strlen( string )
  555.    char *string;
  556.    {
  557.    int r;
  558.  
  559.    r = (unsigned int) _getgtextextent( ((unsigned char far *) string ) );
  560. #ifdef  DEBUG
  561.    if ( r < 0 )
  562.       {
  563.       sprintf( bw_ebuf, "_getgtextent() returned error, string [%s]",
  564.      string );
  565.       bw_error( bw_ebuf );
  566.       }
  567. #endif
  568.    return r;
  569.    }
  570.  
  571. /****************************************************************
  572.  
  573.     gr_rectangle()
  574.  
  575. ****************************************************************/
  576.  
  577. gr_rectangle( screen, x1, y1, x2, y2, color, style )
  578.    int screen;
  579.    int x1, y1, x2, y2;
  580.    int color, style;
  581.    {
  582.    static short _control;
  583.    char *_fill_interior;
  584.  
  585. #if CHECK_PARAMS
  586.    if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
  587.       {
  588.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): x1 value is %d", x1 );
  589.       bw_error( bw_ebuf );
  590.       return BW_ERROR;
  591.       }
  592.    if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
  593.       {
  594.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): x2 value is %d", x2 );
  595.       bw_error( bw_ebuf );
  596.       return BW_ERROR;
  597.       }
  598.    if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
  599.       {
  600.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): y1 value is %d", y1 );
  601.       bw_error( bw_ebuf );
  602.       return BW_ERROR;
  603.       }
  604.    if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
  605.       {
  606.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): y2 value is %d", y2 );
  607.       bw_error( bw_ebuf );
  608.       return BW_ERROR;
  609.       }
  610. #endif
  611.  
  612. #if DEF_RECTANGLE
  613.    def_rectangle( screen, x1, y1, x2, y2, color, style );
  614. #else
  615.    ibm_screen( screen );
  616.  
  617.    switch( style )
  618.       {
  619.       case 0:
  620.          _fill_interior = _fill_blank;
  621.          break;
  622.       case 2:
  623.          _fill_interior = _fill_grid;
  624.          break;
  625.       case 3:
  626.          _fill_interior = _fill_hatch;
  627.          break;
  628.       default:
  629.          _fill_interior = _fill_full;
  630.          break;
  631.       }
  632.    if ( style == HOLLOW )
  633.       {
  634.       _control = _GBORDER;
  635.       }
  636.    else
  637.       {
  638.       _control = _GFILLINTERIOR;
  639.       }
  640.    _setcolor( ibm_color( color ) );
  641.    _setfillmask( _fill_interior );
  642.    if ( screen != GR_HIDDEN )
  643.       {
  644.       msm_hide();
  645.       }
  646.    _rectangle( _control, x1,
  647.       ibm_window->ymax - y1,
  648.       x2,
  649.       ibm_window->ymax - y2 );
  650.    if ( screen != GR_HIDDEN )
  651.       {
  652.       msm_show();
  653.       }
  654. #endif
  655.    }
  656.  
  657. /****************************************************************
  658.  
  659.     gr_circle()
  660.  
  661. ****************************************************************/
  662.  
  663. gr_circle( screen, x, y, radius, color, style )
  664.    int screen;
  665.    int x, y, radius;
  666.    int color, style;
  667.    {
  668.    register int xradius;
  669.    static short _control;
  670.    char *_fill_interior;
  671.  
  672. #if CHECK_PARAMS
  673.    if ( ( x < 0 ) || ( x > ibm_window->xmax ))
  674.       {
  675.       sprintf( bw_ebuf, "[pr:] gr_circle(): x value is %d", x );
  676.       bw_error( bw_ebuf );
  677.       return BW_ERROR;
  678.       }
  679.    if ( ( y < 0 ) || ( y > ibm_window->ymax ))
  680.       {
  681.       sprintf( bw_ebuf, "[pr:] gr_circle(): y value is %d", y );
  682.       bw_error( bw_ebuf );
  683.       return BW_ERROR;
  684.       }
  685. #endif
  686.  
  687. #if DEF_CIRCLE
  688.    def_circle( screen, x, y, radius, color, style );
  689. #else
  690.    ibm_screen( screen );
  691.  
  692.    xradius = ( radius * gr_pysize ) / gr_pxsize;
  693.  
  694.    switch( style )
  695.       {
  696.       case 0:
  697.          _fill_interior = _fill_blank;
  698.          break;
  699.       case 2:
  700.          _fill_interior = _fill_grid;
  701.          break;
  702.       case 3:
  703.          _fill_interior = _fill_hatch;
  704.          break;
  705.       default:
  706.          _fill_interior = _fill_full;
  707.          break;
  708.       }
  709.    if ( style == HOLLOW )
  710.       {
  711.       _control = _GBORDER;
  712.       }
  713.    else
  714.       {
  715.       _control = _GFILLINTERIOR;
  716.       }
  717.    _setcolor( ibm_color( color ) );
  718.    _setfillmask( _fill_interior );
  719.    if ( screen != GR_HIDDEN )
  720.       {
  721.       msm_hide();
  722.       }
  723.    _ellipse( _control, x - xradius,
  724.       ibm_window->ymax - ( y + radius),
  725.       x + xradius,
  726.       ibm_window->ymax - ( y - radius ));
  727.    if ( screen != GR_HIDDEN )
  728.       {
  729.       msm_show();
  730.       }
  731. #endif
  732.    }
  733.  
  734. /****************************************************************
  735.  
  736.     gr_ellipse()
  737.  
  738. ****************************************************************/
  739.  
  740. gr_ellipse( screen, x, y, x_radius, y_radius, mode, color, style )
  741.    int screen;
  742.    int x, y, x_radius, y_radius;
  743.    int mode, color, style;
  744.    {
  745.    }
  746.          
  747. /****************************************************************
  748.  
  749.     gr_clip()
  750.  
  751. ****************************************************************/
  752.  
  753. gr_clip( screen, mode, x1, y1, x2, y2 )
  754.    int screen;
  755.    int mode;
  756.    int x1, y1, x2, y2;
  757.    {
  758.  
  759. #if CHECK_PARAMS
  760.    if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
  761.       {
  762.       sprintf( bw_ebuf, "[pr:] gr_clip(): x1 value is %d", x1 );
  763.       bw_error( bw_ebuf );
  764.       return BW_ERROR;
  765.       }
  766.    if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
  767.       {
  768.       sprintf( bw_ebuf, "[pr:] gr_clip(): x2 value is %d", x2 );
  769.       bw_error( bw_ebuf );
  770.       return BW_ERROR;
  771.       }
  772.    if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
  773.       {
  774.       sprintf( bw_ebuf, "[pr:] gr_clip(): y1 value is %d", y1 );
  775.       bw_error( bw_ebuf );
  776.       return BW_ERROR;
  777.       }
  778.    if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
  779.       {
  780.       sprintf( bw_ebuf, "[pr:] gr_clip(): y2 value is %d", y2 );
  781.       bw_error( bw_ebuf );
  782.       return BW_ERROR;
  783.       }
  784. #endif
  785.  
  786.    ibm_screen( screen );
  787.    if ( mode == FALSE )
  788.       {
  789.       _setcliprgn( 0, 0, ibm_window->xmax - 1,
  790.      ibm_window->ymax - 1 );
  791.       ibm_window->clipping = FALSE;
  792.       return TRUE;
  793.       }
  794.    else
  795.       {
  796.       _setcliprgn( x1, ibm_window->ymax - y2,
  797.      x2, ibm_window->ymax - y1 );
  798.       ibm_window->clipping = TRUE;
  799.       ibm_window->cl_x1 = x1;
  800.       ibm_window->cl_y1 = y1;
  801.       ibm_window->cl_x2 = x2;
  802.       ibm_window->cl_y2 = y2;
  803.       return TRUE;
  804.       }
  805.    }
  806.  
  807. /****************************************************************
  808.  
  809.     gr_font()
  810.  
  811. ****************************************************************/
  812.  
  813. gr_font( screen, type, rq_height )
  814.    int screen;
  815.    int type, rq_height;
  816.    {
  817.    static char fs[ 48 ];
  818.    static int current_type = 0;
  819.    static int current_height = 0;
  820.    static struct _fontinfo fi;
  821.    int x;
  822.  
  823.    ibm_screen( screen );
  824.  
  825.    if ( ( current_type == type ) && ( current_height == rq_height ) )
  826.       {
  827.       return BW_ERROR;
  828.       }
  829.  
  830.    /* first try a bit-mapped (raster-mapped) font */
  831.  
  832.    sprintf( fs, "h%dw%dbr", rq_height, ( rq_height * 2 ) / 3 );
  833.    x = _setfont( fs );
  834.    _getfontinfo( &fi );
  835.    ibm_window->fysize = fi.pixheight;
  836.    ibm_window->fxsize = fi.avgwidth;
  837.  
  838.    /* if this fails ( greater than 5 pixels different than request),
  839.       then try a vector font */
  840.  
  841.    if ( abs( fi.pixheight - rq_height ) > 3 )
  842.       {
  843.       sprintf( fs, "h%dw%dbv", rq_height, ( rq_height * 2 ) / 3 );
  844.       x = _setfont( fs );
  845.       _getfontinfo( &fi );
  846.       ibm_window->fysize = rq_height;
  847.       ibm_window->fxsize = ( rq_height * 2 ) / 3;
  848.       }
  849.  
  850. #ifdef  OLD_DEBUG
  851.    printf( "Request for font: %s\n", fs );
  852.    printf( "_setfont() returned: %d\n", x );
  853.    printf( "fontinfo:  Height, %d  Width, %d  Ascent %d \n",
  854.       fi.pixheight,
  855.       fi.avgwidth, fi.ascent );
  856.    getch();
  857. #endif
  858.    }
  859.  
  860. /****************************************************************
  861.  
  862.     gr_blit()
  863.  
  864. ****************************************************************/
  865.  
  866. gr_blit( src, dst, x1, y1, x2, y2 )
  867.    int src, dst;
  868.    int x1, y1, x2, y2;
  869.    {
  870. #if LINE_BLIT
  871.    register int l;
  872. #endif
  873.  
  874. #if CHECK_PARAMS
  875.    if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
  876.       {
  877.       sprintf( bw_ebuf, "[pr:] gr_blit(): x1 value is %d", x1 );
  878.       bw_error( bw_ebuf );
  879.       return BW_ERROR;
  880.       }
  881.    if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
  882.       {
  883.       sprintf( bw_ebuf, "[pr:] gr_blit(): x2 value is %d", x2 );
  884.       bw_error( bw_ebuf );
  885.       return BW_ERROR;
  886.       }
  887.    if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
  888.       {
  889.       sprintf( bw_ebuf, "[pr:] gr_blit(): y1 value is %d", y1 );
  890.       bw_error( bw_ebuf );
  891.       return BW_ERROR;
  892.       }
  893.    if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
  894.       {
  895.       sprintf( bw_ebuf, "[pr:] gr_blit(): y2 value is %d", y2 );
  896.       bw_error( bw_ebuf );
  897.       return BW_ERROR;
  898.       }
  899.    if ( src == dst )
  900.       {
  901.       sprintf( bw_ebuf, "[pr:] gr_blit(): src == dst" );
  902.       bw_error( bw_ebuf );
  903.       return BW_ERROR;
  904.       }
  905. #endif
  906.  
  907.    if ( ibm_vc.numvideopages > 1 )
  908.       {
  909.       msm_hide();
  910.  
  911.       /* if the area is the entire screen, use fast blit routine */
  912.  
  913.       if ( ( ( x2 - x1 ) == ibm_window->xmax  )
  914.      && ( ( y2 - y1 ) == ibm_window->ymax ))
  915.      {
  916. #ifdef  OLD_DEBUG
  917.      fprintf( stderr, "This is the fast blit routine. \n" );
  918.      getch();
  919. #endif
  920.      if ( src == GR_PRIMARY )
  921.         {
  922.         if ( ibm_vmode == _HERCMONO )
  923.            {
  924.            movedata( (unsigned int) 0xb000,         /* source segment */
  925.             (unsigned int) 0x0000,              /* source offset */
  926.             (unsigned int) 0xb800,              /* dest segment */
  927.             (unsigned int) 0x0000,              /* dest offset */
  928.             (unsigned) 0x8000 );                /* number bytes */
  929.            }
  930.         else if ( ibm_vmode == _ERESCOLOR )
  931.            {
  932.            outp(0x3ce, 0x05);      /* Mode register select */
  933.            outp(0x3cf, 0x01);      /* Select write mode 1 */
  934.            outp(0x3ce, 0x03);      /* Merge mode */
  935.            outp(0x3cf, 0x00);      /* Replace mode */
  936.            outp(0x3ce, 0x03);      /* Bit Mask register */
  937.            outp(0x3cf, 0xff);      /* Select all bits */
  938.            movedata( 0xA000, 0x0000, 0xA800, 0x0000, 0x8000 );
  939.            }
  940.         }
  941.      else
  942.         {
  943.         if ( ibm_vmode == _HERCMONO )
  944.            {
  945.            movedata( (unsigned int) 0xb800,
  946.             (unsigned int) 0x0000,
  947.             (unsigned int) 0xb000,
  948.             (unsigned int) 0x0000,
  949.             (unsigned) 0x8000 );
  950.  
  951.            }
  952.         if ( ibm_vmode == _ERESCOLOR )
  953.            {
  954.            outp(0x3ce, 0x05);      /* Mode register select */
  955.            outp(0x3cf, 0x01);      /* Select write mode 1 */
  956.            outp(0x3ce, 0x03);      /* Merge mode */
  957.            outp(0x3cf, 0x00);      /* Replace mode */
  958.            outp(0x3ce, 0x03);      /* Bit Mask register */
  959.            outp(0x3cf, 0xff);      /* Select all bits */
  960.            movedata( 0xA800, 0x0000, 0xA000, 0x0000, 0x8000 );
  961.            }
  962.         }
  963.      }
  964.  
  965.       /* The area is not the complete screen; blit only part of it */
  966.  
  967.       else
  968.      {
  969. #ifdef  OLD_DEBUG
  970.      fprintf( stderr, "DEBUG: imsize will be %ld bytes \n",
  971.         _imagesize( x1, y2, x2, y1 ) );
  972.      getch();
  973. #endif
  974.  
  975. #if     LINE_BLIT
  976.      for ( l = y2; l >= y1; --l )
  977.         {
  978.         ibm_screen( src );
  979.         _getimage( x1, ibm_window->ymax - l, x2, ibm_window->ymax - l,
  980.            xfr_mem );
  981.         ibm_screen( dst );
  982.         _putimage( x1, ibm_window->ymax - l, xfr_mem, _GPSET );
  983.         }
  984. #else
  985.      ibm_screen( src );
  986.      _getimage( x1, ibm_window->ymax - y2, x2, ibm_window->ymax - y1,
  987.         xfr_mem );
  988.      ibm_screen( dst );
  989.      _putimage( x1, ibm_window->ymax - y2, xfr_mem, _GPSET );
  990. #endif
  991.      }
  992.       }
  993.    msm_show();
  994.    return TRUE;
  995.    }
  996.  
  997. /****************************************************************
  998.  
  999.     gr_imsave()
  1000.  
  1001. ****************************************************************/
  1002.  
  1003. gr_imsave( screen, mode, x1, y1, x2, y2, image )
  1004.    int screen;
  1005.    int mode, x1, y1, x2, y2;
  1006.    int *image;
  1007.    {
  1008.    register int r;
  1009.    int carry_on;
  1010.  
  1011. #if CHECK_PARAMS
  1012.    if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
  1013.       {
  1014.       sprintf( bw_ebuf, "[pr:] gr_save(): x1 value is %d", x1 );
  1015.       bw_error( bw_ebuf );
  1016.       return BW_ERROR;
  1017.       }
  1018.    if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
  1019.       {
  1020.       sprintf( bw_ebuf, "[pr:] gr_save(): x2 value is %d", x2 );
  1021.       bw_error( bw_ebuf );
  1022.       return BW_ERROR;
  1023.       }
  1024.    if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
  1025.       {
  1026.       sprintf( bw_ebuf, "[pr:] gr_save(): y1 value is %d", y1 );
  1027.       bw_error( bw_ebuf );
  1028.       return BW_ERROR;
  1029.       }
  1030.    if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
  1031.       {
  1032.       sprintf( bw_ebuf, "[pr:] gr_save(): y2 value is %d", y2 );
  1033.       bw_error( bw_ebuf );
  1034.       return BW_ERROR;
  1035.       }
  1036. #endif
  1037.  
  1038.    ibm_screen( screen );
  1039.  
  1040.    msm_hide();
  1041.  
  1042.    switch ( mode )
  1043.       {
  1044.       case TRUE:                   /* TRUE = SAVE image */
  1045. #ifdef  OLD_DEBUG
  1046.      printf( "DEBUG: saving screen %d, %d %d %d %d\n", screen, x1, y1,
  1047.         x2, y2 );
  1048.      getch();
  1049. #endif
  1050.  
  1051.      /* find an available buffer */
  1052.  
  1053.      carry_on = TRUE;
  1054.      r = 0;
  1055.      while( ( carry_on == TRUE ) && ( r < IMAGES ) )
  1056.         {
  1057.         if ( ibm_images[ r ] == NULL )
  1058.            {
  1059.            carry_on = FALSE;
  1060.            }
  1061.         else
  1062.            {
  1063.            ++r;
  1064.            }
  1065.         }
  1066.  
  1067.      if ( r >= IMAGES )
  1068.         {
  1069.         bw_error( "No more slots for image storage" );
  1070.         return FALSE;
  1071.         }
  1072.  
  1073.      *image = r;
  1074.  
  1075.      /* get memory */
  1076.  
  1077.      if ( ( ibm_images[ *image ] = malloc( (size_t) _imagesize(
  1078.         x1, ibm_window->ymax - y2,
  1079.         x2, ibm_window->ymax - y1 ) ) ) == NULL )
  1080.         {
  1081.         bw_error( "Out of memory to store image" );
  1082.         return FALSE;
  1083.         }
  1084.  
  1085.      /* save the image */
  1086.  
  1087.      _getimage( x1, ( ibm_window->ymax ) - y2, x2,
  1088.         ( ibm_window->ymax ) - y1,
  1089.         ibm_images[ *image ] );
  1090.  
  1091.      break;
  1092.  
  1093.       case FALSE:                  /* FALSE = RESTORE image */
  1094.  
  1095. #ifdef  OLD_DEBUG
  1096.      printf( "DEBUG: restoring screen %d, %d %d %d %d\n", screen,
  1097.         x1, y1, x2, y2 );
  1098.      getch();
  1099. #endif
  1100.  
  1101. #ifdef DEBUG
  1102.      if ( ibm_images[ *image ] == NULL )
  1103.         {
  1104.         bw_error( "gr_imsave(): NULL image requested" );
  1105.         return FALSE;
  1106.         }
  1107. #endif
  1108.  
  1109.      _putimage( x1, ibm_window->ymax - y2, ibm_images[ *image ], _GPSET );
  1110.      break;
  1111.       default:
  1112. #ifdef  DEBUG
  1113.      bw_error( "[pr:] gr_save(): incorrect mode" );
  1114. #endif
  1115.      msm_show();
  1116.      return BW_ERROR;
  1117.      break;
  1118.       }
  1119.  
  1120.    msm_show();
  1121.    }
  1122.  
  1123. /****************************************************************
  1124.  
  1125.     gr_imfree()
  1126.  
  1127. ****************************************************************/
  1128.  
  1129. gr_imfree( image )
  1130.    int image;
  1131.    {
  1132.  
  1133. #ifdef DEBUG
  1134.    if ( ibm_images[ image ] == NULL )
  1135.       {
  1136.       bw_error( "gr_imfree(): NULL image requested" );
  1137.       return FALSE;
  1138.       }
  1139. #endif
  1140.  
  1141.    free( ibm_images[ image ] );
  1142.    ibm_images[ image ] = NULL;
  1143.  
  1144.    }
  1145.  
  1146. /****************************************************************
  1147.  
  1148.     gr_mouse()
  1149.  
  1150. ****************************************************************/
  1151.  
  1152. gr_mouse( mode, x, y, buttons )
  1153.    int mode;
  1154.    int *x, *y;
  1155.    int *buttons;
  1156.    {
  1157.    static int m_pending = FALSE, y_pos = 0, x_pos = 0;
  1158.  
  1159.    switch( mode )
  1160.       {
  1161.       case HIDE:
  1162.      msm_hide();
  1163.      break;
  1164.       case SHOW:
  1165.      msm_show();
  1166.      break;
  1167.       case POSITION:
  1168.      msm_hide();
  1169.      msm_position( ibm_window->ymax - *y, *x );
  1170.      msm_show();
  1171.      break;
  1172.       case STATUS:
  1173.       case SAMPLE:
  1174.          if ( m_pending == TRUE )
  1175.             {
  1176.             return TRUE;
  1177.             }
  1178.          if ( msm_read() == TRUE )
  1179.             {
  1180.             x_pos = *x = m_col;
  1181.             y_pos = *y = m_row;
  1182.             m_pending = TRUE;
  1183.             return TRUE;
  1184.             }
  1185.          else
  1186.             {
  1187.             x_pos = *x = m_col;
  1188.             y_pos = *y = m_row;
  1189.         return BW_ERROR;
  1190.             }
  1191.          break;
  1192.       case WAIT:
  1193.          if ( m_pending == TRUE )
  1194.             {
  1195.             m_pending = FALSE;
  1196.             *x = x_pos;
  1197.             *y = y_pos;
  1198.             return TRUE;
  1199.             }
  1200.          while( msm_read() == FALSE )
  1201.             {
  1202.             ;
  1203.             }
  1204.          *x = x_pos = m_col;
  1205.          *y = y_pos = m_row;
  1206.          return TRUE;
  1207.          break;
  1208.       default:
  1209.          break;
  1210.       }
  1211.    }
  1212.  
  1213. /****************************************************************
  1214.  
  1215.     ibm_    IBM PC (tm) specific routines
  1216.  
  1217. ****************************************************************/
  1218.  
  1219. ibm_screen( screen )
  1220.    int screen;
  1221.    {
  1222.    static int x_screen = 599;
  1223.  
  1224. #if CHECK_PARAMS
  1225.    if ( ( screen < 0 ) || ( screen > GR_HIDDEN ))
  1226.       {
  1227.       sprintf( bw_ebuf, "[pr:] ibm_screen(): incorrect screen number %d",
  1228.      screen );
  1229.       bw_error( bw_ebuf );
  1230.       }
  1231. #endif
  1232.  
  1233.    if ( screen != x_screen )
  1234.       {
  1235.       _setactivepage( screen );
  1236.       x_screen = screen;
  1237.       }
  1238.    }
  1239.  
  1240. ibm_color( color )
  1241.    int color;
  1242.    {
  1243.    switch( color )
  1244.       {
  1245.       case 0:
  1246.          return 0;
  1247.       case 1:
  1248.          return 15;
  1249.       case 2:
  1250.          return 12;
  1251.       case 3:
  1252.          return 10;
  1253.       case 4:
  1254.          return 9;
  1255.       case 5:
  1256.          return 14;
  1257.       case 6:
  1258.          return 11;
  1259.       case 7:
  1260.          return 13;
  1261.       case 8:
  1262.          return 0;
  1263.       case 9:
  1264.          return 15;
  1265.       case 10:
  1266.          return 4;
  1267.       case 11:
  1268.          return 2;
  1269.       case 12:
  1270.          return 1;
  1271.       case 13:
  1272.          return 5;
  1273.       case 14:
  1274.          return 3;
  1275.       case 15:
  1276.          return 6;
  1277.       default:
  1278.          return 1;
  1279.       }
  1280.    }
  1281.  
  1282. /****************************************************************
  1283.  
  1284.     msm_    Microsoft Mouse Routines
  1285.  
  1286. ****************************************************************/
  1287.  
  1288. msm_init()
  1289.    {
  1290.  
  1291.    /* if the video card is hercules, set the appropriate location */
  1292.  
  1293.    if ( ibm_vmode == _HERCMONO )
  1294.       {
  1295. #ifdef OLD_DEBUG
  1296.       fprintf( stderr, "Hercules graphics mouse implementation.\n" );
  1297.       getchar();
  1298. #endif
  1299.       hgc_location = (char far *) 0x00400049;
  1300.       *hgc_location = 6;                       /* use 5 for HGC CRT page 1 */
  1301.       }
  1302.  
  1303.    /* check if the mouse driver exists first */
  1304.  
  1305.    ibm_registers.x.ax = 0x3533;       /* look at the interrupt 33 address */
  1306.  
  1307.    int86x( 0x21, &ibm_registers, &ibm_registers, &segreg);
  1308.    miaddr = (( (long) segreg.es) << 16) + (long) ibm_registers.x.bx;
  1309.    if ( miaddr == 0 || *(char *) miaddr == 0xcf)
  1310.       {
  1311.       msm_exist = FALSE;
  1312.       return BW_ERROR;
  1313.       }
  1314.  
  1315.    /* and then check for the mouse itself */
  1316.  
  1317.    ibm_registers.x.ax = 0;                    /* mouse status flag */
  1318.    int86( 0x33, &ibm_registers, &ibm_registers);         /* check for the mouse interupt */
  1319.    msm_exist = (ibm_registers.x.ax != 0);
  1320.    msm_buttons = ibm_registers.x.bx;
  1321.    if ( msm_exist == FALSE)
  1322.       {
  1323. #ifdef OLD_DEBUG
  1324.       fprintf( stderr, "Found mouse driver, but no mouse\n" );
  1325.       getchar();
  1326. #endif
  1327.       return BW_ERROR;
  1328.       }
  1329.  
  1330.    /* Set minimum/maximum lines, columns */
  1331.  
  1332.    switch ( ibm_vmode )
  1333.       {
  1334.       case _HERCMONO:
  1335.      msm_bounds( 347, 719 );
  1336.      break;
  1337.       case _HRESBW:
  1338.      msm_bounds( 199, 639 );
  1339.      break;
  1340.       case _ERESCOLOR:
  1341.      msm_bounds( 349, 639 );
  1342.      break;
  1343.       default:
  1344. #ifdef  DEBUG
  1345.      fprintf( stderr, "Unknown video mode in mouse initialization <%d>\n", ibm_vmode );
  1346.      getchar();
  1347. #endif
  1348.      break;
  1349.       }
  1350.  
  1351.    return TRUE;
  1352.  
  1353.    }
  1354.  
  1355. msm_bounds( lines, columns )
  1356.    int lines, columns;
  1357.    {
  1358.  
  1359.    ibm_registers.x.ax = 7;            /* set min/max horizontal cursor position */
  1360.    ibm_registers.x.cx = 0;            /* start at 0 */
  1361.    ibm_registers.x.dx = columns - 1;
  1362.    int86( 0x33, &ibm_registers, &ibm_registers);
  1363.  
  1364.    ibm_registers.x.ax = 8;            /* set min/max vertical cursor position */
  1365.    ibm_registers.x.cx = 0;            /* start at 0 */
  1366.    ibm_registers.x.dx = lines - 1;     /* end at the end */
  1367.    int86( 0x33, &ibm_registers, &ibm_registers);
  1368.  
  1369.    }
  1370.  
  1371. msm_show()
  1372.    {
  1373. #ifdef  OLD_DEBUG
  1374.    fprintf( stderr, "+" );
  1375. #endif
  1376.  
  1377.    while( msm_showcounter < 0 )
  1378.       {
  1379.       ibm_registers.x.ax = 1;            /* show cursor */
  1380.       int86( 0x33, &ibm_registers, &ibm_registers);
  1381.       ++msm_showcounter;
  1382.       }
  1383.    }
  1384.  
  1385. msm_hide()
  1386.    {
  1387. #ifdef  OLD_DEBUG
  1388.    fprintf( stderr, "-" );
  1389. #endif
  1390.    while( msm_showcounter >= 0 )
  1391.       {
  1392.       ibm_registers.x.ax = 2;            /* hide cursor */
  1393.       int86( 0x33, &ibm_registers, &ibm_registers);
  1394.       --msm_showcounter;
  1395.       }
  1396.    }
  1397.  
  1398. msm_position( line, column )
  1399.    {
  1400.    ibm_registers.x.ax = 4;            /* set mouse cursor position */
  1401.    ibm_registers.x.cx = column;
  1402.    ibm_registers.x.dx = line;
  1403.    int86( 0x33, &ibm_registers, &ibm_registers);
  1404.    }
  1405.  
  1406. msm_read()
  1407.    {
  1408.    register int k;         /* current bit/button of mouse */
  1409.    register int event;     /* encoded mouse event */
  1410.    int newbut;             /* new state of the mouse buttons */
  1411.    int mousecol;           /* current mouse column */
  1412.    int mouserow;           /* current mouse row */
  1413.    int sstate;             /* current shift key status */
  1414.  
  1415.    /* check to see if any mouse buttons are different */
  1416.  
  1417.    ibm_registers.x.ax = 3;    /* Get button status and mouse position */
  1418.    int86(0x33, &ibm_registers, &ibm_registers);
  1419.    newbut   = ibm_registers.x.bx;
  1420. #ifdef OLDSTUFF
  1421.    mousecol = ibm_registers.x.cx >> 3;
  1422.    mouserow = ibm_registers.x.dx >> 3;
  1423. #else
  1424.    mousecol = ibm_registers.x.cx;
  1425.    mouserow = ibm_registers.x.dx;
  1426. #endif
  1427.    m_col = mousecol;
  1428.    m_row = ( ibm_vc.numypixels - 1 ) - ( mouserow );
  1429.  
  1430.    /* get the shift key status as well */
  1431.  
  1432.    sstate = 0;
  1433.    ibm_registers.h.ah = 2;    /* return current shift status */
  1434.    int86( 0x16, &ibm_registers, &ibm_registers);
  1435.    sstate = ibm_registers.h.al;
  1436.  
  1437.    for ( k = 1; k != (1 << msm_buttons); k = k<<1)
  1438.       {
  1439.  
  1440.       /* For each button on the mouse */
  1441.  
  1442.       if ((msm_oldbut&k) != (newbut&k))
  1443.          {
  1444.  
  1445.          /* This button changed, generate an event */
  1446.  
  1447.          msm_oldbut = newbut;
  1448.          return ( TRUE );
  1449.          }
  1450.       }
  1451.    return ( FALSE );
  1452.    }
  1453.  
  1454.  
  1455.  
  1456.